package com.partner.sys.attach.core.service;

import com.alibaba.fastjson.JSON;
import com.partner.common.api.AttachMainApi;
import com.partner.common.core.constant.QueryConstant;
import com.partner.common.core.dto.*;
import com.partner.common.core.entity.AbstractEntity;
import com.partner.common.core.service.AbstractServiceImpl;
import com.partner.common.dto.partner.SysAttachMainVO;
import com.partner.common.entity.SysAttachMain;
import com.partner.common.util.IDGenerator;
import com.partner.sys.attach.api.SysAttachMainApi;
import com.partner.sys.attach.core.mapper.SysAttachMainMapper;
import com.partner.sys.attach.core.util.FileUploadUtils;
import com.partner.sys.attach.dto.SysAttachBindVO;
import io.swagger.annotations.Api;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.collections.CollectionUtils;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Service;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
import org.springframework.web.multipart.MultipartFile;

import java.io.IOException;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.stream.Collectors;
import java.util.stream.Stream;

/**
 * 附件文件Service业务层处理
 *
 * @author partner
 */
@Service
@Slf4j
@Api(hidden = true)
@RestController
@RequestMapping("/api/attach/main")
public class SysAttachMainService extends AbstractServiceImpl<SysAttachMainMapper, SysAttachMain, SysAttachMainVO> implements SysAttachMainApi, AttachMainApi {
    @Autowired
    private SysAttachMainMapper sysAttachMainMapper;

    public static List<String> baseColumns = Stream.of("fdId", "fdAnonymous", "fdAttachType", "fdDownloadUrl", "fdFileExtName", "fdFileName", "fdFileSize", "fdHeight", "fdMimeType", "fdWidth", "fdDownloadNumber", "fdStatus", "fdOrder", "fdEntityId", "fdEntityKey", "fdEntityName", "fdAttachFileId").collect(Collectors.toList());

    public static List<String> titles = Stream.of("主键", "匿名可访问", "文件类型", "下载地址", "扩展名", "文件名", "文件大小", "图片或视频高度", "文件格式类型", "图片或视频宽度", "下载次数", "附件状态", "顺序", "业务实体Id", "业务类型字段", "业务类型名称", "借款原因").collect(Collectors.toList());


    protected List<String> getBaseColumns() {
        return SysAttachMainService.baseColumns;
    }

    protected List<String> getTitels() {
        return SysAttachMainService.titles;
    }

    /**
     * 资源映射路径 前缀
     */
    @Value("${attach.prefix:/resource}")
    public String localFilePrefix;

    /**
     * 域名或本机访问地址
     */
    @Value("${attach.domain:localhost:8080}")
    public String domain;

    /**
     * 上传文件存储在本地的根路径
     */
    @Value("${attach.path:D:/nginx/html/resource}")
    private String localFilePath;

    public SysAttachMainVO uploadFile(MultipartFile file) {
        String name = null;
        try {
            name = FileUploadUtils.upload(localFilePath, file);
        } catch (IOException e) {
            log.error("保存附件报错");
        }
        SysAttachMainVO attachMainVO = new SysAttachMainVO();
        attachMainVO.setFdId(IDGenerator.generateID());
        //附件类型
        attachMainVO.setFdAttachType("image");
        //
        attachMainVO.setFdDownloadUrl(localFilePath + name);
        String fileName = name.substring(name.lastIndexOf("/") + 1, name.length());
        attachMainVO.setFdFileName(fileName);
        attachMainVO.setFdFileSize(file.getSize());
        //文件格式类型
        String fileType = name.substring(name.lastIndexOf(".") + 1, name.length());
        attachMainVO.setFdMimeType(fileType);


        this.repository.add(attachMainVO);
        attachMainVO.setFdDownloadUrl(localFilePrefix + name);
        return attachMainVO;
    }

    @Override
    public void bind(SysAttachBindVO bindVO) {
        log.info("远程调用请求附件绑定，bindVO = {}", JSON.toJSONString(bindVO));
        if (bindVO == null) {
            return;
        }
        if (StringUtils.isEmpty(bindVO.getFdEntityId()) || StringUtils.isEmpty(bindVO.getFdEntityName())) {
            log.warn("远程调用请求附件绑定，主文档ID或文档类别不为空!");
            return;
        }
        //处理删除附件逻辑
        bindDeletedAttachFiles(bindVO);

        bindAddedAttachFiles(bindVO);

    }

    @Override
    public List<SysAttachMainVO> listByEntity(MechanismDTO mechanismDTO) {
        String fdEntityName = mechanismDTO.getFdEntityName();
        String fdEntityId = mechanismDTO.getFdEntityId();

        QueryRequest request = new QueryRequest();

        request.addCondition("fd_entity_name", QueryConstant.Operator.eqProp, fdEntityName);
        request.addCondition("fd_entity_id", QueryConstant.Operator.eqProp, fdEntityId);


        List<SysAttachMainVO> sysAttachMainVOList = this.repository.findAll(request);

        return sysAttachMainVOList;
    }

    @Override
    public void deleteByEntity(MechanismDTO mechanismDTO) {
        sysAttachMainMapper.deleteByMechanismDTO(mechanismDTO);
    }

    /**
     * 新增附件处理逻辑
     *
     * @param bindVO
     * @return
     */
    private void bindAddedAttachFiles(SysAttachBindVO bindVO) {
        List<SysAttachMainVO> addedAttachFiles = bindVO.getAddedAttachFiles();
        Map<String, List<String>> keyMap = new HashMap<>();
        for (SysAttachMainVO attachFile : addedAttachFiles) {
            if (!keyMap.containsKey(attachFile.getFdEntityKey())) {
                keyMap.put(attachFile.getFdEntityKey(), new ArrayList<>());
            }
            keyMap.get(attachFile.getFdEntityKey()).add(attachFile.getFdId());
        }
        for (Map.Entry<String, List<String>> entry : keyMap.entrySet()) {
            MechanismIds mechanismIds = MechanismIds.of(bindVO.getFdEntityName(), bindVO.getFdEntityId(), entry.getKey(), entry.getValue());
            this.repository.setEntities(mechanismIds);
        }
    }

    /**
     * 删除附件处理逻辑
     *
     * @param bindVO
     */
    private void bindDeletedAttachFiles(SysAttachBindVO bindVO) {
        // 删除的附件列表执行删除数据库attachMain
        List<SysAttachMainVO> deletedAttachFiles = bindVO.getDeletedAttachFiles();
        if (CollectionUtils.isEmpty(deletedAttachFiles)) {
            return;
        }
        List<String> fdIds = deletedAttachFiles.stream().map(AbstractEntity::getFdId).collect(Collectors.toList());
        this.batchDel(IdsDTO.of(fdIds));
    }

    @Override
    public SysAttachMainVO getAttach(IdVO idVO) {
        return this.get(UniqueVO.of(idVO.getFdId()));
    }
}
